﻿using System;
using System.Configuration;
using System.Collections.Generic;
using System.Collections;
using System.Linq;

namespace NDBGen.Configuration
{
    public class GenericElementCollection<T> : ConfigurationElementCollection, IEnumerable<T>
        where T : ConfigurationElement, ICollectionItemElement, new()
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new T();
        }

        protected override Object GetElementKey(ConfigurationElement element)
        {
            return ((ICollectionItemElement)element).Key;
        }

        #region [ IEnumerable<TDescriptor> Members ]

        public IEnumerator<T> GetEnumerator()
        {
            return new GenericEnumerator(base.GetEnumerator());
        }

        #endregion

        public T Get(Object key)
        {
            return (T)this.BaseGet(key);
        }

        public class GenericEnumerator : IEnumerator<T>
        {
            IEnumerator _innerEnumerator;

            internal GenericEnumerator(IEnumerator innerEnumerator)
            {
                _innerEnumerator = innerEnumerator;
            }

            public T Current
            {
                get { return (T)_innerEnumerator.Current; }
            }

            public void Dispose() { }
            
            Object IEnumerator.Current
            {
                get { return _innerEnumerator.Current; }
            }

            public Boolean MoveNext()
            {
                return _innerEnumerator.MoveNext();
            }

            public void Reset()
            {
                _innerEnumerator.Reset();
            }
        }

        internal void Add(T element)
        {
            this.BaseAdd(element);
        }
    }
}